"""Middleware components for the FastAPI application."""

from fastapi import Request, Response
from fastapi.middleware.base import BaseHTTPMiddleware
import logging
import time

logger = logging.getLogger(__name__)


def error_handler_middleware(debug: bool = False):
    """Error handling middleware factory."""
    class ErrorHandlerMiddleware(BaseHTTPMiddleware):
        async def dispatch(self, request: Request, call_next):
            try:
                response = await call_next(request)
                return response
            except Exception as e:
                if debug:
                    logger.exception(f"Request failed: {str(e)}")
                else:
                    logger.error(f"Request failed: {str(e)}")
                return Response(
                    content=f'{{"error": "Internal server error", "detail": "{str(e) if debug else "Something went wrong"}"}}',
                    status_code=500,
                    media_type="application/json"
                )
    return ErrorHandlerMiddleware


def request_logger_middleware(log_requests: bool = True, log_responses: bool = False):
    """Request logging middleware factory."""
    class RequestLoggerMiddleware(BaseHTTPMiddleware):
        async def dispatch(self, request: Request, call_next):
            start_time = time.time()
            
            if log_requests:
                logger.info(f"{request.method} {request.url}")
            
            response = await call_next(request)
            
            duration = time.time() - start_time
            if log_responses:
                logger.info(f"Response: {response.status_code} in {duration:.3f}s")
            
            return response
    return RequestLoggerMiddleware


def response_formatter_middleware(format_responses: bool = True, add_metadata: bool = False):
    """Response formatting middleware factory."""
    class ResponseFormatterMiddleware(BaseHTTPMiddleware):
        async def dispatch(self, request: Request, call_next):
            response = await call_next(request)
            return response
    return ResponseFormatterMiddleware


def rate_limiter_middleware(enabled: bool = False, requests_per_window: int = 100, 
                          window_seconds: int = 60, ip_whitelist: list = None, 
                          skip_paths: list = None):
    """Rate limiting middleware factory."""
    class RateLimiterMiddleware(BaseHTTPMiddleware):
        async def dispatch(self, request: Request, call_next):
            if not enabled:
                return await call_next(request)
            
            # Skip rate limiting for whitelisted paths
            if skip_paths and any(request.url.path.startswith(path) for path in skip_paths):
                return await call_next(request)
            
            return await call_next(request)
    return RateLimiterMiddleware


def authentication_middleware(enabled: bool = False, api_key: str = None,
                            api_key_header: str = "X-API-Key", 
                            skip_paths: list = None, public_paths: list = None):
    """Authentication middleware factory."""
    class AuthenticationMiddleware(BaseHTTPMiddleware):
        async def dispatch(self, request: Request, call_next):
            if not enabled:
                return await call_next(request)
            
            # Skip auth for public paths
            if skip_paths and any(request.url.path.startswith(path) for path in skip_paths):
                return await call_next(request)
            
            return await call_next(request)
    return AuthenticationMiddleware


def security_headers_middleware(add_security_headers: bool = True):
    """Security headers middleware factory."""
    class SecurityHeadersMiddleware(BaseHTTPMiddleware):
        async def dispatch(self, request: Request, call_next):
            response = await call_next(request)
            
            if add_security_headers:
                response.headers["X-Content-Type-Options"] = "nosniff"
                response.headers["X-Frame-Options"] = "DENY"
                response.headers["X-XSS-Protection"] = "1; mode=block"
            
            return response
    return SecurityHeadersMiddleware